`include "macro.v"
module ALU (
    input wire [3:0] alu_op,
    output reg [31:0] c,
    output wire eq,
    output wire lt,
    output wire ltu,
    // alua_sel
    input wire alua_sel,
    input wire [31:0] rD1,
    input wire [31:0] pc,
    // alub_sel
    input wire alub_sel,
    input wire [31:0] rD2,
    input wire [31:0] ext
);

wire [31:0] a = alua_sel == `ALUA_RD1 ? rD1 : pc;
wire [31:0] b = alub_sel == `ALUB_RD2 ? rD2 : ext;

assign eq = a == b;
assign lt = $signed(a) < $signed(b);
assign ltu = $unsigned(a) < $unsigned(b);

always @(*) begin
    case (alu_op)
        `ALU_ADD : c = a + b;
        `ALU_SUB : c = a - b;
        `ALU_AND : c = a & b;
        `ALU_OR  : c = a | b;
        `ALU_XOR : c = a ^ b;
        `ALU_SLL : c = a << b[4:0];
        `ALU_SRL : c = a >> b[4:0];
        `ALU_SRA : c = $signed(a) >>> b[4:0];
        `ALU_SLT : c = lt ? 'b1 : 'b0;
        `ALU_SLTU: c = ltu ? 'b1 : 'b0;
        default  : c = 'b0;
    endcase
end


endmodule